import re
from concurrent.futures import ThreadPoolExecutor

from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search, Q, A
from requests import request as http

from app.service_quality.models.qos_traffic_statistics import QosTrafficStatistics
from common.database import SessionLocal
from common.utils import cst_to_utc
from core.logger import logger


def japi_openresty_status(opts):
    nginx_status_data = http("GET", "http://{address}:{port}{url}".format(**opts)).text
    req_active = re.search(r'Active connections:\s+(\d+)', nginx_status_data).group
    req_conn_stats = re.search(r'\s+(\d+)\s+(\d+)\s+(\d+)', nginx_status_data).group
    req_io_stats = re.search(r'Reading:\s*(\d+)\s*Writing:\s*(\d+)\s*Waiting:\s*(\d+)', nginx_status_data).group
    data = {"active_connections": req_active(1), "server_accepts": req_conn_stats(1), "server_handled": req_conn_stats(2),
            "server_requests": req_conn_stats(3), "reading": req_io_stats(1), "writing": req_io_stats(2), "waiting": req_io_stats(3)}

    return data


def japi_server_requests(opts):
    data = 0
    db = SessionLocal()
    try:
        ex = ThreadPoolExecutor(max_workers=2)
        res_iter = ex.map(japi_openresty_status, opts)
        for res in res_iter:
            data += int(res.get('server_requests'))
        QosTrafficStatistics.add(db, {"item": "japi_qpm", "value": data})
        logger.info(f"japi_qpm insert table qos_traffic_statistics Successful")
        return True
    except Exception as e:
        logger.error(f"japi_qpm japi_qpminsert table qos_traffic_statistics Exception {e}")
        return False
    finally:
        db.close()


def pv_and_uv_agg_query(es_client: Elasticsearch, index: str, cst_begin_time: str, cst_end_time: str,
                        search_filters=None) -> bool:
    if search_filters is None:
        search_filters = []
    f = Q({'range': {'@timestamp': {"from": cst_to_utc(cst_begin_time), "to": cst_to_utc(cst_end_time)}}}) & \
        Q('bool', should=[Q("term", domain_name__keyword=search_filter) for search_filter in search_filters if search_filters])

    s = Search(using=es_client, index=index)
    s = s.filter(f)
    s.aggs.bucket('mobile_terms', A('cardinality', field='user_mobile.keyword'))
    response = s.execute()
    db = SessionLocal()
    try:
        QosTrafficStatistics.add(db, {"item": "pv", "value": response.hits.total})
        QosTrafficStatistics.add(db, {"item": "uv", "value": response.aggs.mobile_terms["value"]})
        logger.info(f"pv and uv insert table qos_traffic_statistics Successful")
        return True
    except Exception as e:
        logger.error(f"pv and uv insert table qos_traffic_statistics Exception {e}")
        return False
    finally:
        db.close()
